{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "ddc91ad8-99a6-4b5e-9da8-badd668beefc",
   "metadata": {},
   "source": [
    "## 引入：mean estimation\n",
    "\n",
    "该算法的目的是通过“采样”估计expectation\n",
    "\n",
    "$w_{k+1}^{} = \\frac{1}{k} \\sum_{i=1}^{k} x_{i} , \\ \\ \\ \\  k=1,2,...$\n",
    "\n",
    "$w_{k+1}$ ：下标是k+1，但这个是前k个元素的均值\n",
    "\n",
    "这个是定义式，已知一系列随机变量$X$的采样，求**mean estimation**，估计其expectation"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "08508c02-57b0-4b27-80c3-d775f497c430",
   "metadata": {},
   "source": [
    "$RM:\\  g(w)=0$\n",
    "\n",
    "$SGD:\\  g'(w)=0$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3c2089b9-2063-4cc2-ae15-74fdf4d820ca",
   "metadata": {},
   "source": [
    "#### 一、定义式：直接求平均"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7a2f93a6-dc41-4037-ba1d-9883c33c995b",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-04-27T09:15:47.368573Z",
     "start_time": "2025-04-27T09:15:46.679603Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "def f(x):\n",
    "    return x**3-5\n",
    "x = np.random.normal(10, 1, 10000) # 均值，方差，个数，正态分布\n",
    "\n",
    "plt.hist(x, bins=100, range=(0, 20), edgecolor='black')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "0b1c379e-3582-4ca6-b171-beca4d84ed9d",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-04-27T09:16:05.980197Z",
     "start_time": "2025-04-27T09:16:05.977027Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1029.737223812185"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f(x).mean() #直接求平均"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4add074b-1e41-4a06-8538-487fd29c4d2a",
   "metadata": {},
   "source": [
    "#### 二、迭代式\n",
    "$w_{k+1}^{} = \\frac{1}{k} \\sum_{i=1}^{k} x_{i} ,\\ \\ \\ \\  k=1,2,...$\n",
    "\n",
    "$w_{k}^{} = \\frac{1}{k-1} \\sum_{i=1}^{k-1} x_{i} ,\\ \\ \\ \\  k=2,3,...$\n",
    "\n",
    "$w_{k+1}^{} = \\frac{1}{k} \\sum_{i=1}^{k} = \\frac{1}{k}(\\sum_{i=1}^{k-1} x_{i} +  x_{k})=\\frac{1}{k}((k-1)w_{k} + x_{k})=w_{k} - \\frac{1}{k}(w_{k}-x_{k})$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a4b32f87-5289-4531-81d3-55d3489e6b7a",
   "metadata": {},
   "source": [
    "$k=0 \\ \\ w_{1}= 0$\n",
    "\n",
    "$k=1 \\ \\ w_{2}= \\frac{1}{1} * f(x1) =  0 - \\frac{1}{1}(0 - f(x_{1})) = w_{1} - \\frac{1}{1}(w_{1} - f(x_{1}))$\n",
    "\n",
    "$k=2 \\ \\ w_{3}= \\frac{1}{2} * [f(x1)+f(x2)] = w_{2} - \\frac{1}{2}(w_{2} - f(x_{2}))$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "d0074303-4762-476c-920e-6c06ca9f1b59",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-04-27T09:16:21.497558Z",
     "start_time": "2025-04-27T09:16:21.492309Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1029.7715700934762\n"
     ]
    }
   ],
   "source": [
    "w = 0  #w1\n",
    "for k in range(1,10000):\n",
    "    w = w - 1/k*(w-f(x[k-1]))  #数组下标是从0开始的，所以记得-1\n",
    "    # print(w)\n",
    "print(w)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "6d99ef79-b6c7-4f6a-8e5f-94dc35c54973",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1027.715932664409\n"
     ]
    }
   ],
   "source": [
    "w = 0  #w1\n",
    "for k in range(1,10000):\n",
    "    w = w - 1/(k+20)*(w-f(x[k-1]))  #实际上k+什么常数最终都能收敛\n",
    "    # print(w)\n",
    "print(w)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "94efb0a8-4060-4f8b-870f-a7a21d69bf3a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1033.507779928496\n"
     ]
    }
   ],
   "source": [
    "w = 0  #w1\n",
    "for k in range(1,10000):\n",
    "    w = w - 1/1000*(w-f(x[k-1]))  #实际上k+什么常数最终都能收敛\n",
    "    # print(w)\n",
    "print(w)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b01a3c5e-d52f-4b4a-86f8-8cf414a0bd6b",
   "metadata": {},
   "source": [
    "## Robbins-Monro\n",
    "\n",
    "下面是三个RM算法的例子\n",
    "\n",
    "$w_{k+1} = w_{k} - a_{k}\\widetilde{g} (w_{k},\\eta_{k}),\\ \\ \\ \\ k=1,2,3...$\n",
    "\n",
    "$f(x) = x - 10$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "fe9c89be-664c-42a0-8b30-d589c1e1ee02",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-04-27T09:19:18.968355Z",
     "start_time": "2025-04-27T09:19:18.959387Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10.0\n",
      "[505.0, 257.5, 133.75, 71.875, 40.9375, 25.46875, 17.734375, 13.8671875, 11.93359375, 10.966796875, 10.4833984375, 10.24169921875, 10.120849609375, 10.0604248046875, 10.03021240234375, 10.015106201171875, 10.007553100585938, 10.003776550292969, 10.001888275146484, 10.000944137573242]\n"
     ]
    }
   ],
   "source": [
    "f = lambda x: x-10   #f(x) = x-10\n",
    "\n",
    "w = 1000\n",
    "a = 0.5\n",
    "tmp = []\n",
    "for i in range(65535):\n",
    "    # w = w - 1/(i+1) * f(w)\n",
    "    w = w - a * f(w)\n",
    "    tmp.append(w)\n",
    "print(w)\n",
    "print(tmp[:20])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b0a0aaa1-4cc5-4e7d-8fe4-f8c86d1a5bfe",
   "metadata": {},
   "source": "$f(x) = x^{3} - 5$"
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "8344cf17-dc50-4e01-a024-aa5fc9644be4",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-04-27T09:59:47.947846Z",
     "start_time": "2025-04-27T09:59:47.936252Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.7099759466766962\n",
      "[1.7870000000000006, 1.4337247984999977, 2.118019100824119, 0.9926580786105648, 1.7970309683099193, 1.6631662037090005, 1.7202347282382884, 1.7089182851913267, 1.7099485213505834, 1.7099725786067483, 1.7099752645004416, 1.7099757631741106, 1.7099758869967476, 1.7099759243907242, 1.70997593742364, 1.7099759424966594, 1.7099759446535718, 1.709975945639514, 1.709975946118368, 1.7099759463632525]\n"
     ]
    }
   ],
   "source": [
    "f = lambda x: x**3-5   #f(x) = x^3-5\n",
    "\n",
    "w = 1.7   # 注意，这里方程的梯度是二次方，无上界，所以对初始取值很苛刻，不然极其容易无法收敛，如果w太大就无法收敛\n",
    "tmp = []\n",
    "for i in range(65535):\n",
    "    w = w - 1/(i+1) * f(w)  \n",
    "    # w = w - 0.5 * f(w)  \n",
    "    tmp.append(w)\n",
    "print(w)\n",
    "print(tmp[:20])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "0027b414",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4.912999999999999"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "1.7**3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "80bdd549-1c68-4df2-a125-6de03880ff5c",
   "metadata": {},
   "source": [
    "$f(x) = \\tan^{-1}(x-1)$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "7fc71f20",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.0"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "math.atan(0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "c031144a-5cdc-4458-bf5d-e1355c19ae4e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.000000000000111\n",
      "[99.9984393043398, 99.99687860883881, 99.99531791349706, 99.99375721831454, 99.99219652329126, 99.99063582842722, 99.98907513372242, 99.98751443917689, 99.98595374479062, 99.98439305056361, 99.98283235649588, 99.98127166258742, 99.97971096883823, 99.97815027524834, 99.97658958181773, 99.97502888854642, 99.9734681954344, 99.9719075024817, 99.9703468096883, 99.96878611705421]\n"
     ]
    }
   ],
   "source": [
    "import math\n",
    "f = lambda x: math.atan(x-1)   #f(x) = atan(x-1)\n",
    "\n",
    "#w越大，需要迭代次数较多才能收敛\n",
    "w = 100\n",
    "tmp = []\n",
    "for i in range(655300):\n",
    "    w = w - 1/1000 * f(w)  #\n",
    "    tmp.append(w)\n",
    "print(w)\n",
    "print(tmp[:20])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ed9a9e8c-dac0-409c-b4a0-c0624ab26e8a",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "c0546420-0aa4-478c-a211-97ea0e9794ed",
   "metadata": {},
   "source": [
    "### RM（Robbins-Monro）算法收敛的三大条件\n",
    "\n",
    "1、方程的**梯度**有上下界\n",
    "\n",
    "2、折扣因子a，减少的不能太快也不能太慢，收敛性介于调和级数和二次方的p级数之间\n",
    "\n",
    "3、噪声的期望得是0，并且方差是有界的（这个很显然，如果噪声期望不是0，那就一定有误差）"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "81881332-8f49-47a1-92db-f9b8ebf763cb",
   "metadata": {},
   "source": [
    "### mean estimate算法是RM算法的证明：\n",
    "\n",
    "考虑方程：$g(w) = w - E[x]$\n",
    "\n",
    "显然若能解出 $g(w^{*}) = 0$ 那么相当于解得 $w^{*} = E[x]$\n",
    "\n",
    "$\\widetilde{g} (w,\\eta) = w - x= w-x+E[x]-E[x] = (w-E[x])+(E[x]-x) = g(w)+ \\eta $\n",
    "\n",
    "即：$g(w) = w-E[x]$  误差$\\eta = E[x]-x$\n",
    "\n",
    "显然误差的期望和方差是符合条件的， 然后梯度是常数，折扣因子是$1/k$ 三个条件都满足"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "402a9616-b83f-4628-bb41-56400a29cd13",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
